#pragma once

#include <cstdint>
#include <stdlib.h>
#include <thread>
#include <string>
#include <SFML\Network.hpp>

namespace CATSERVER {
	struct ProtocolInfo {

		uint32_t PacketLength;

		uint16_t HeaderLength;

		uint16_t Version;

		uint32_t Action;
	};

	static ProtocolInfo* GetProtocolInfo(char* buffer, unsigned int size) {
		if (size < 12)
			return NULL;
		ProtocolInfo* _info = (ProtocolInfo*)malloc(sizeof(ProtocolInfo));
		_info->PacketLength = _byteswap_ulong(*reinterpret_cast<int32_t*>(buffer));
		_info->HeaderLength = _byteswap_ushort(*reinterpret_cast<int16_t*>(buffer + 4));
		_info->Version = _byteswap_ushort(*reinterpret_cast<int16_t*>(buffer + 6));
		_info->Action = _byteswap_ulong(*reinterpret_cast<int32_t*>(buffer + 8));

		return _info;
	}
	class CatServer {
	public:

		CatServer();

		~CatServer();

		void (*ReceivedDataEvt)(int action,char* data,unsigned int size);

		void (*DisconnectEvt)();	

		void (*LogMessageEvt)(const char* format, ...);
	
		void StartServer(int port);
		
		void StopServer();

	private:
		//socket define
		static const int SEND_BUF_SIZE = 64 * 1024;
		static const int RECV_BUF_SIZE = 64 * 1024;

		//server define
		unsigned int server_port;

		//server state
		bool isRun;

		std::thread * server;
		sf::TcpListener listener;

		void ReceiveMessageLoop();

		void ProcessData(int action, char* buffer, int size);

		void _disconnect();

	};

}